home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / Kubuntu 8.10 / kubuntu-8.10-desktop-i386.iso / casper / filesystem.squashfs / usr / lib / python2.5 / trace.pyc (.txt) < prev    next >
Python Compiled Bytecode  |  2008-10-29  |  22KB  |  723 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.5)
  3.  
  4. '''program/module to trace Python program or function execution
  5.  
  6. Sample use, command line:
  7.   trace.py -c -f counts --ignore-dir \'$prefix\' spam.py eggs
  8.   trace.py -t --ignore-dir \'$prefix\' spam.py eggs
  9.   trace.py --trackcalls spam.py eggs
  10.  
  11. Sample use, programmatically
  12.   import sys
  13.  
  14.   # create a Trace object, telling it what to ignore, and whether to
  15.   # do tracing or line-counting or both.
  16.   tracer = trace.Trace(ignoredirs=[sys.prefix, sys.exec_prefix,], trace=0,
  17.                     count=1)
  18.   # run the new command using the given tracer
  19.   tracer.run(\'main()\')
  20.   # make a report, placing output in /tmp
  21.   r = tracer.results()
  22.   r.write_results(show_missing=True, coverdir="/tmp")
  23. '''
  24. import linecache
  25. import os
  26. import re
  27. import sys
  28. import threading
  29. import token
  30. import tokenize
  31. import types
  32. import gc
  33.  
  34. try:
  35.     import cPickle
  36.     pickle = cPickle
  37. except ImportError:
  38.     import pickle
  39.  
  40.  
  41. def usage(outfile):
  42.     outfile.write("Usage: %s [OPTIONS] <file> [ARGS]\n\nMeta-options:\n--help                Display this help then exit.\n--version             Output version information then exit.\n\nOtherwise, exactly one of the following three options must be given:\n-t, --trace           Print each line to sys.stdout before it is executed.\n-c, --count           Count the number of times each line is executed\n                      and write the counts to <module>.cover for each\n                      module executed, in the module's directory.\n                      See also `--coverdir', `--file', `--no-report' below.\n-l, --listfuncs       Keep track of which functions are executed at least\n                      once and write the results to sys.stdout after the\n                      program exits.\n-T, --trackcalls      Keep track of caller/called pairs and write the\n                      results to sys.stdout after the program exits.\n-r, --report          Generate a report from a counts file; do not execute\n                      any code.  `--file' must specify the results file to\n                      read, which must have been created in a previous run\n                      with `--count --file=FILE'.\n\nModifiers:\n-f, --file=<file>     File to accumulate counts over several runs.\n-R, --no-report       Do not generate the coverage report files.\n                      Useful if you want to accumulate over several runs.\n-C, --coverdir=<dir>  Directory where the report files.  The coverage\n                      report for <package>.<module> is written to file\n                      <dir>/<package>/<module>.cover.\n-m, --missing         Annotate executable lines that were not executed\n                      with '>>>>>> '.\n-s, --summary         Write a brief summary on stdout for each file.\n                      (Can only be used with --count or --report.)\n\nFilters, may be repeated multiple times:\n--ignore-module=<mod> Ignore the given module and its submodules\n                      (if it is a package).\n--ignore-dir=<dir>    Ignore files in the given directory (multiple\n                      directories can be joined by os.pathsep).\n" % sys.argv[0])
  43.  
  44. PRAGMA_NOCOVER = '#pragma NO COVER'
  45. rx_blank = re.compile('^\\s*(#.*)?$')
  46.  
  47. class Ignore:
  48.     
  49.     def __init__(self, modules = None, dirs = None):
  50.         if not modules:
  51.             pass
  52.         self._mods = []
  53.         if not dirs:
  54.             pass
  55.         self._dirs = []
  56.         self._dirs = map(os.path.normpath, self._dirs)
  57.         self._ignore = {
  58.             '<string>': 1 }
  59.  
  60.     
  61.     def names(self, filename, modulename):
  62.         if self._ignore.has_key(modulename):
  63.             return self._ignore[modulename]
  64.         
  65.         for mod in self._mods:
  66.             if mod == modulename:
  67.                 self._ignore[modulename] = 1
  68.                 return 1
  69.             
  70.             n = len(mod)
  71.             if mod == modulename[:n] and modulename[n] == '.':
  72.                 self._ignore[modulename] = 1
  73.                 return 1
  74.                 continue
  75.         
  76.         if filename is None:
  77.             self._ignore[modulename] = 1
  78.             return 1
  79.         
  80.         for d in self._dirs:
  81.             if filename.startswith(d + os.sep):
  82.                 self._ignore[modulename] = 1
  83.                 return 1
  84.                 continue
  85.         
  86.         self._ignore[modulename] = 0
  87.         return 0
  88.  
  89.  
  90.  
  91. def modname(path):
  92.     '''Return a plausible module name for the patch.'''
  93.     base = os.path.basename(path)
  94.     (filename, ext) = os.path.splitext(base)
  95.     return filename
  96.  
  97.  
  98. def fullmodname(path):
  99.     '''Return a plausible module name for the path.'''
  100.     comparepath = os.path.normcase(path)
  101.     longest = ''
  102.     for dir in sys.path:
  103.         dir = os.path.normcase(dir)
  104.         if comparepath.startswith(dir) and comparepath[len(dir)] == os.sep:
  105.             if len(dir) > len(longest):
  106.                 longest = dir
  107.             
  108.         len(dir) > len(longest)
  109.     
  110.     if longest:
  111.         base = path[len(longest) + 1:]
  112.     else:
  113.         base = path
  114.     base = base.replace(os.sep, '.')
  115.     if os.altsep:
  116.         base = base.replace(os.altsep, '.')
  117.     
  118.     (filename, ext) = os.path.splitext(base)
  119.     return filename
  120.  
  121.  
  122. class CoverageResults:
  123.     
  124.     def __init__(self, counts = None, calledfuncs = None, infile = None, callers = None, outfile = None):
  125.         self.counts = counts
  126.         if self.counts is None:
  127.             self.counts = { }
  128.         
  129.         self.counter = self.counts.copy()
  130.         self.calledfuncs = calledfuncs
  131.         if self.calledfuncs is None:
  132.             self.calledfuncs = { }
  133.         
  134.         self.calledfuncs = self.calledfuncs.copy()
  135.         self.callers = callers
  136.         if self.callers is None:
  137.             self.callers = { }
  138.         
  139.         self.callers = self.callers.copy()
  140.         self.infile = infile
  141.         self.outfile = outfile
  142.         if self.infile:
  143.             
  144.             try:
  145.                 (counts, calledfuncs, callers) = pickle.load(open(self.infile, 'rb'))
  146.                 self.update(self.__class__(counts, calledfuncs, callers))
  147.             except (IOError, EOFError, ValueError):
  148.                 err = None
  149.                 print >>sys.stderr, 'Skipping counts file %r: %s' % (self.infile, err)
  150.             except:
  151.                 None<EXCEPTION MATCH>(IOError, EOFError, ValueError)
  152.             
  153.  
  154.         None<EXCEPTION MATCH>(IOError, EOFError, ValueError)
  155.  
  156.     
  157.     def update(self, other):
  158.         '''Merge in the data from another CoverageResults'''
  159.         counts = self.counts
  160.         calledfuncs = self.calledfuncs
  161.         callers = self.callers
  162.         other_counts = other.counts
  163.         other_calledfuncs = other.calledfuncs
  164.         other_callers = other.callers
  165.         for key in other_counts.keys():
  166.             counts[key] = counts.get(key, 0) + other_counts[key]
  167.         
  168.         for key in other_calledfuncs.keys():
  169.             calledfuncs[key] = 1
  170.         
  171.         for key in other_callers.keys():
  172.             callers[key] = 1
  173.         
  174.  
  175.     
  176.     def write_results(self, show_missing = True, summary = False, coverdir = None):
  177.         '''
  178.         @param coverdir
  179.         '''
  180.         if self.calledfuncs:
  181.             print 
  182.             print 'functions called:'
  183.             calls = self.calledfuncs.keys()
  184.             calls.sort()
  185.             for filename, modulename, funcname in calls:
  186.                 print 'filename: %s, modulename: %s, funcname: %s' % (filename, modulename, funcname)
  187.             
  188.         
  189.         if self.callers:
  190.             print 
  191.             print 'calling relationships:'
  192.             calls = self.callers.keys()
  193.             calls.sort()
  194.             lastfile = lastcfile = ''
  195.             for pfile, pmod, pfunc in calls:
  196.                 (cfile, cmod, cfunc) = None
  197.                 if pfile != lastfile:
  198.                     print 
  199.                     print '***', pfile, '***'
  200.                     lastfile = pfile
  201.                     lastcfile = ''
  202.                 
  203.                 if cfile != pfile and lastcfile != cfile:
  204.                     print '  -->', cfile
  205.                     lastcfile = cfile
  206.                 
  207.                 print '    %s.%s -> %s.%s' % (pmod, pfunc, cmod, cfunc)
  208.             
  209.         
  210.         per_file = { }
  211.         for filename, lineno in self.counts.keys():
  212.             lines_hit = per_file[filename] = per_file.get(filename, { })
  213.             lines_hit[lineno] = self.counts[(filename, lineno)]
  214.         
  215.         sums = { }
  216.         for filename, count in per_file.iteritems():
  217.             if filename == '<string>':
  218.                 continue
  219.             
  220.             if filename.startswith('<doctest '):
  221.                 continue
  222.             
  223.             if filename.endswith(('.pyc', '.pyo')):
  224.                 filename = filename[:-1]
  225.             
  226.             if coverdir is None:
  227.                 dir = os.path.dirname(os.path.abspath(filename))
  228.                 modulename = modname(filename)
  229.             else:
  230.                 dir = coverdir
  231.                 if not os.path.exists(dir):
  232.                     os.makedirs(dir)
  233.                 
  234.                 modulename = fullmodname(filename)
  235.             if show_missing:
  236.                 lnotab = find_executable_linenos(filename)
  237.             else:
  238.                 lnotab = { }
  239.             source = linecache.getlines(filename)
  240.             coverpath = os.path.join(dir, modulename + '.cover')
  241.             (n_hits, n_lines) = self.write_results_file(coverpath, source, lnotab, count)
  242.             if summary and n_lines:
  243.                 percent = int(100 * n_hits / n_lines)
  244.                 sums[modulename] = (n_lines, percent, modulename, filename)
  245.                 continue
  246.         
  247.         if summary and sums:
  248.             mods = sums.keys()
  249.             mods.sort()
  250.             print 'lines   cov%   module   (path)'
  251.             for m in mods:
  252.                 (n_lines, percent, modulename, filename) = sums[m]
  253.                 print '%5d   %3d%%   %s   (%s)' % sums[m]
  254.             
  255.         
  256.         if self.outfile:
  257.             
  258.             try:
  259.                 pickle.dump((self.counts, self.calledfuncs, self.callers), open(self.outfile, 'wb'), 1)
  260.             except IOError:
  261.                 err = None
  262.                 print >>sys.stderr, "Can't save counts files because %s" % err
  263.             except:
  264.                 None<EXCEPTION MATCH>IOError
  265.             
  266.  
  267.         None<EXCEPTION MATCH>IOError
  268.  
  269.     
  270.     def write_results_file(self, path, lines, lnotab, lines_hit):
  271.         '''Return a coverage results file in path.'''
  272.         
  273.         try:
  274.             outfile = open(path, 'w')
  275.         except IOError:
  276.             err = None
  277.             print >>sys.stderr, 'trace: Could not open %r for writing: %s- skipping' % (path, err)
  278.             return (0, 0)
  279.  
  280.         n_lines = 0
  281.         n_hits = 0
  282.         for i, line in enumerate(lines):
  283.             lineno = i + 1
  284.             if lineno in lines_hit:
  285.                 outfile.write('%5d: ' % lines_hit[lineno])
  286.                 n_hits += 1
  287.                 n_lines += 1
  288.             elif rx_blank.match(line):
  289.                 outfile.write('       ')
  290.             elif lineno in lnotab and PRAGMA_NOCOVER not in lines[i]:
  291.                 outfile.write('>>>>>> ')
  292.                 n_lines += 1
  293.             else:
  294.                 outfile.write('       ')
  295.             outfile.write(lines[i].expandtabs(8))
  296.         
  297.         outfile.close()
  298.         return (n_hits, n_lines)
  299.  
  300.  
  301.  
  302. def find_lines_from_code(code, strs):
  303.     '''Return dict where keys are lines in the line number table.'''
  304.     linenos = { }
  305.     line_increments = [ ord(c) for c in code.co_lnotab[1::2] ]
  306.     table_length = len(line_increments)
  307.     docstring = False
  308.     lineno = code.co_firstlineno
  309.     for li in line_increments:
  310.         lineno += li
  311.         if lineno not in strs:
  312.             linenos[lineno] = 1
  313.             continue
  314.         []
  315.     
  316.     return linenos
  317.  
  318.  
  319. def find_lines(code, strs):
  320.     '''Return lineno dict for all code objects reachable from code.'''
  321.     linenos = find_lines_from_code(code, strs)
  322.     for c in code.co_consts:
  323.         if isinstance(c, types.CodeType):
  324.             linenos.update(find_lines(c, strs))
  325.             continue
  326.     
  327.     return linenos
  328.  
  329.  
  330. def find_strings(filename):
  331.     '''Return a dict of possible docstring positions.
  332.  
  333.     The dict maps line numbers to strings.  There is an entry for
  334.     line that contains only a string or a part of a triple-quoted
  335.     string.
  336.     '''
  337.     d = { }
  338.     prev_ttype = token.INDENT
  339.     f = open(filename)
  340.     for ttype, tstr, start, end, line in tokenize.generate_tokens(f.readline):
  341.         if ttype == token.STRING:
  342.             if prev_ttype == token.INDENT:
  343.                 (sline, scol) = start
  344.                 (eline, ecol) = end
  345.                 for i in range(sline, eline + 1):
  346.                     d[i] = 1
  347.                 
  348.             
  349.         
  350.         prev_ttype = ttype
  351.     
  352.     f.close()
  353.     return d
  354.  
  355.  
  356. def find_executable_linenos(filename):
  357.     '''Return dict where keys are line numbers in the line number table.'''
  358.     
  359.     try:
  360.         prog = open(filename, 'rU').read()
  361.     except IOError:
  362.         err = None
  363.         print >>sys.stderr, 'Not printing coverage data for %r: %s' % (filename, err)
  364.         return { }
  365.  
  366.     code = compile(prog, filename, 'exec')
  367.     strs = find_strings(filename)
  368.     return find_lines(code, strs)
  369.  
  370.  
  371. class Trace:
  372.     
  373.     def __init__(self, count = 1, trace = 1, countfuncs = 0, countcallers = 0, ignoremods = (), ignoredirs = (), infile = None, outfile = None):
  374.         """
  375.         @param count true iff it should count number of times each
  376.                      line is executed
  377.         @param trace true iff it should print out each line that is
  378.                      being counted
  379.         @param countfuncs true iff it should just output a list of
  380.                      (filename, modulename, funcname,) for functions
  381.                      that were called at least once;  This overrides
  382.                      `count' and `trace'
  383.         @param ignoremods a list of the names of modules to ignore
  384.         @param ignoredirs a list of the names of directories to ignore
  385.                      all of the (recursive) contents of
  386.         @param infile file from which to read stored counts to be
  387.                      added into the results
  388.         @param outfile file in which to write the results
  389.         """
  390.         self.infile = infile
  391.         self.outfile = outfile
  392.         self.ignore = Ignore(ignoremods, ignoredirs)
  393.         self.counts = { }
  394.         self.blabbed = { }
  395.         self.pathtobasename = { }
  396.         self.donothing = 0
  397.         self.trace = trace
  398.         self._calledfuncs = { }
  399.         self._callers = { }
  400.         self._caller_cache = { }
  401.         if countcallers:
  402.             self.globaltrace = self.globaltrace_trackcallers
  403.         elif countfuncs:
  404.             self.globaltrace = self.globaltrace_countfuncs
  405.         elif trace and count:
  406.             self.globaltrace = self.globaltrace_lt
  407.             self.localtrace = self.localtrace_trace_and_count
  408.         elif trace:
  409.             self.globaltrace = self.globaltrace_lt
  410.             self.localtrace = self.localtrace_trace
  411.         elif count:
  412.             self.globaltrace = self.globaltrace_lt
  413.             self.localtrace = self.localtrace_count
  414.         else:
  415.             self.donothing = 1
  416.  
  417.     
  418.     def run(self, cmd):
  419.         import __main__ as __main__
  420.         dict = __main__.__dict__
  421.         if not self.donothing:
  422.             sys.settrace(self.globaltrace)
  423.             threading.settrace(self.globaltrace)
  424.         
  425.         
  426.         try:
  427.             exec cmd in dict, dict
  428.         finally:
  429.             if not self.donothing:
  430.                 sys.settrace(None)
  431.                 threading.settrace(None)
  432.             
  433.  
  434.  
  435.     
  436.     def runctx(self, cmd, globals = None, locals = None):
  437.         if globals is None:
  438.             globals = { }
  439.         
  440.         if locals is None:
  441.             locals = { }
  442.         
  443.         if not self.donothing:
  444.             sys.settrace(self.globaltrace)
  445.             threading.settrace(self.globaltrace)
  446.         
  447.         
  448.         try:
  449.             exec cmd in globals, locals
  450.         finally:
  451.             if not self.donothing:
  452.                 sys.settrace(None)
  453.                 threading.settrace(None)
  454.             
  455.  
  456.  
  457.     
  458.     def runfunc(self, func, *args, **kw):
  459.         result = None
  460.         if not self.donothing:
  461.             sys.settrace(self.globaltrace)
  462.         
  463.         
  464.         try:
  465.             result = func(*args, **kw)
  466.         finally:
  467.             if not self.donothing:
  468.                 sys.settrace(None)
  469.             
  470.  
  471.         return result
  472.  
  473.     
  474.     def file_module_function_of(self, frame):
  475.         code = frame.f_code
  476.         filename = code.co_filename
  477.         if filename:
  478.             modulename = modname(filename)
  479.         else:
  480.             modulename = None
  481.         funcname = code.co_name
  482.         clsname = None
  483.         return (filename, modulename, funcname)
  484.  
  485.     
  486.     def globaltrace_trackcallers(self, frame, why, arg):
  487.         '''Handler for call events.
  488.  
  489.         Adds information about who called who to the self._callers dict.
  490.         '''
  491.         if why == 'call':
  492.             this_func = self.file_module_function_of(frame)
  493.             parent_func = self.file_module_function_of(frame.f_back)
  494.             self._callers[(parent_func, this_func)] = 1
  495.         
  496.  
  497.     
  498.     def globaltrace_countfuncs(self, frame, why, arg):
  499.         '''Handler for call events.
  500.  
  501.         Adds (filename, modulename, funcname) to the self._calledfuncs dict.
  502.         '''
  503.         if why == 'call':
  504.             this_func = self.file_module_function_of(frame)
  505.             self._calledfuncs[this_func] = 1
  506.         
  507.  
  508.     
  509.     def globaltrace_lt(self, frame, why, arg):
  510.         """Handler for call events.
  511.  
  512.         If the code block being entered is to be ignored, returns `None',
  513.         else returns self.localtrace.
  514.         """
  515.         if why == 'call':
  516.             code = frame.f_code
  517.             filename = frame.f_globals.get('__file__', None)
  518.             if filename:
  519.                 modulename = modname(filename)
  520.                 if modulename is not None:
  521.                     ignore_it = self.ignore.names(filename, modulename)
  522.                     if not ignore_it:
  523.                         if self.trace:
  524.                             print ' --- modulename: %s, funcname: %s' % (modulename, code.co_name)
  525.                         
  526.                         return self.localtrace
  527.                     
  528.                 
  529.             else:
  530.                 return None
  531.         
  532.  
  533.     
  534.     def localtrace_trace_and_count(self, frame, why, arg):
  535.         if why == 'line':
  536.             filename = frame.f_code.co_filename
  537.             lineno = frame.f_lineno
  538.             key = (filename, lineno)
  539.             self.counts[key] = self.counts.get(key, 0) + 1
  540.             bname = os.path.basename(filename)
  541.             print '%s(%d): %s' % (bname, lineno, linecache.getline(filename, lineno)),
  542.         
  543.         return self.localtrace
  544.  
  545.     
  546.     def localtrace_trace(self, frame, why, arg):
  547.         if why == 'line':
  548.             filename = frame.f_code.co_filename
  549.             lineno = frame.f_lineno
  550.             bname = os.path.basename(filename)
  551.             print '%s(%d): %s' % (bname, lineno, linecache.getline(filename, lineno)),
  552.         
  553.         return self.localtrace
  554.  
  555.     
  556.     def localtrace_count(self, frame, why, arg):
  557.         if why == 'line':
  558.             filename = frame.f_code.co_filename
  559.             lineno = frame.f_lineno
  560.             key = (filename, lineno)
  561.             self.counts[key] = self.counts.get(key, 0) + 1
  562.         
  563.         return self.localtrace
  564.  
  565.     
  566.     def results(self):
  567.         return CoverageResults(self.counts, infile = self.infile, outfile = self.outfile, calledfuncs = self._calledfuncs, callers = self._callers)
  568.  
  569.  
  570.  
  571. def _err_exit(msg):
  572.     sys.stderr.write('%s: %s\n' % (sys.argv[0], msg))
  573.     sys.exit(1)
  574.  
  575.  
  576. def main(argv = None):
  577.     import getopt as getopt
  578.     if argv is None:
  579.         argv = sys.argv
  580.     
  581.     
  582.     try:
  583.         (opts, prog_argv) = getopt.getopt(argv[1:], 'tcrRf:d:msC:lT', [
  584.             'help',
  585.             'version',
  586.             'trace',
  587.             'count',
  588.             'report',
  589.             'no-report',
  590.             'summary',
  591.             'file=',
  592.             'missing',
  593.             'ignore-module=',
  594.             'ignore-dir=',
  595.             'coverdir=',
  596.             'listfuncs',
  597.             'trackcalls'])
  598.     except getopt.error:
  599.         msg = None
  600.         sys.stderr.write('%s: %s\n' % (sys.argv[0], msg))
  601.         sys.stderr.write("Try `%s --help' for more information\n" % sys.argv[0])
  602.         sys.exit(1)
  603.  
  604.     trace = 0
  605.     count = 0
  606.     report = 0
  607.     no_report = 0
  608.     counts_file = None
  609.     missing = 0
  610.     ignore_modules = []
  611.     ignore_dirs = []
  612.     coverdir = None
  613.     summary = 0
  614.     listfuncs = False
  615.     countcallers = False
  616.     for opt, val in opts:
  617.         if opt == '--help':
  618.             usage(sys.stdout)
  619.             sys.exit(0)
  620.         
  621.         if opt == '--version':
  622.             sys.stdout.write('trace 2.0\n')
  623.             sys.exit(0)
  624.         
  625.         if opt == '-T' or opt == '--trackcalls':
  626.             countcallers = True
  627.             continue
  628.         
  629.         if opt == '-l' or opt == '--listfuncs':
  630.             listfuncs = True
  631.             continue
  632.         
  633.         if opt == '-t' or opt == '--trace':
  634.             trace = 1
  635.             continue
  636.         
  637.         if opt == '-c' or opt == '--count':
  638.             count = 1
  639.             continue
  640.         
  641.         if opt == '-r' or opt == '--report':
  642.             report = 1
  643.             continue
  644.         
  645.         if opt == '-R' or opt == '--no-report':
  646.             no_report = 1
  647.             continue
  648.         
  649.         if opt == '-f' or opt == '--file':
  650.             counts_file = val
  651.             continue
  652.         
  653.         if opt == '-m' or opt == '--missing':
  654.             missing = 1
  655.             continue
  656.         
  657.         if opt == '-C' or opt == '--coverdir':
  658.             coverdir = val
  659.             continue
  660.         
  661.         if opt == '-s' or opt == '--summary':
  662.             summary = 1
  663.             continue
  664.         
  665.         if opt == '--ignore-module':
  666.             ignore_modules.append(val)
  667.             continue
  668.         
  669.         if opt == '--ignore-dir':
  670.             for s in val.split(os.pathsep):
  671.                 s = os.path.expandvars(s)
  672.                 s = s.replace('$prefix', os.path.join(sys.prefix, 'lib', 'python' + sys.version[:3]))
  673.                 s = s.replace('$exec_prefix', os.path.join(sys.exec_prefix, 'lib', 'python' + sys.version[:3]))
  674.                 s = os.path.normpath(s)
  675.                 ignore_dirs.append(s)
  676.             
  677.             continue
  678.         
  679.         if not 0:
  680.             raise AssertionError, 'Should never get here'
  681.     
  682.     if listfuncs:
  683.         if count or trace:
  684.             _err_exit('cannot specify both --listfuncs and (--trace or --count)')
  685.         
  686.     if not count and trace and report and listfuncs or countcallers:
  687.         _err_exit('must specify one of --trace, --count, --report, --listfuncs, or --trackcalls')
  688.     
  689.     if report and no_report:
  690.         _err_exit('cannot specify both --report and --no-report')
  691.     
  692.     if report and not counts_file:
  693.         _err_exit('--report requires a --file')
  694.     
  695.     if no_report and len(prog_argv) == 0:
  696.         _err_exit('missing name of file to run')
  697.     
  698.     if report:
  699.         results = CoverageResults(infile = counts_file, outfile = counts_file)
  700.         results.write_results(missing, summary = summary, coverdir = coverdir)
  701.     else:
  702.         sys.argv = prog_argv
  703.         progname = prog_argv[0]
  704.         sys.path[0] = os.path.split(progname)[0]
  705.         t = Trace(count, trace, countfuncs = listfuncs, countcallers = countcallers, ignoremods = ignore_modules, ignoredirs = ignore_dirs, infile = counts_file, outfile = counts_file)
  706.         
  707.         try:
  708.             t.run('execfile(%r)' % (progname,))
  709.         except IOError:
  710.             err = None
  711.             _err_exit('Cannot run file %r because: %s' % (sys.argv[0], err))
  712.         except SystemExit:
  713.             pass
  714.  
  715.         results = t.results()
  716.         if not no_report:
  717.             results.write_results(missing, summary = summary, coverdir = coverdir)
  718.         
  719.  
  720. if __name__ == '__main__':
  721.     main()
  722.  
  723.